package cn.iocoder.yudao.module.infra.service.nacos;

import cn.iocoder.yudao.module.infra.constants.InfraNacosConstants;
import cn.iocoder.yudao.module.infra.dal.redis.nacos.NacosLockRedisDAO;
import cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.Properties;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;

@Service
@Slf4j
public class NacosConfigServiceImpl implements INacosConfigService {
    @Resource
    private com.alibaba.nacos.api.config.ConfigService nacosConfigService;

    @Resource
    private NacosLockRedisDAO nacosLockRedisDAO;

    @Override
    public void setValue(String key, Object value) {
        nacosLockRedisDAO.lockGlobal(() -> {
            final Properties properties = getProperties();
            if (value == null) {
                properties.remove(key);
            } else {
                properties.put(key, value);
            }
            log.info("更新Nacos配置, key = {}, value = {}", key, value);

            try (StringWriter writer = new StringWriter()) {
                properties.store(writer, null);
                final String propertiesString = writer.toString();
                nacosConfigService.publishConfig(InfraNacosConstants.DATA_ID, InfraNacosConstants.GROUP, propertiesString);
            } catch (Exception e) {
                throw exception(ErrorCodeConstants.CONFIG_SET_VALUE_ERROR, e.getMessage());
            }

            return null;
        });
    }

    @Override
    public Properties getProperties() {
        return nacosLockRedisDAO.lockGlobal(() -> {
            try {
                final String propertiesString = nacosConfigService.getConfig(InfraNacosConstants.DATA_ID, InfraNacosConstants.GROUP, 5000);

                final Properties properties = new Properties();
                try (StringReader reader = new StringReader(propertiesString)) {
                    properties.load(reader);
                }
                return properties;
            } catch (Exception e) {
                throw exception(ErrorCodeConstants.CONFIG_GET_VALUE_ERROR, e.getMessage());
            }
        });
    }

}
